/* * #! * % * Copyright (C) 2014 - 2016 Humboldt-Universität zu Berlin * % * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * #_ */ package de.hub.cs.dbis.aeolus.monitoring.microbenchmarks; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.HashMap; import org.apache.thrift7.TException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import backtype.storm.Config; import backtype.storm.StormSubmitter; import backtype.storm.generated.AlreadyAliveException; import backtype.storm.generated.ExecutorSummary; import backtype.storm.generated.InvalidTopologyException; import backtype.storm.generated.KillOptions; import backtype.storm.generated.Nimbus.Client; import backtype.storm.generated.NotAliveException; import backtype.storm.generated.TopologyInfo; import backtype.storm.topology.IRichBolt; import backtype.storm.topology.IRichSpout; import backtype.storm.topology.TopologyBuilder; import backtype.storm.utils.NimbusClient; import backtype.storm.utils.Utils; import de.hub.cs.dbis.aeolus.batching.api.InputDebatcher; import de.hub.cs.dbis.aeolus.batching.api.SpoutOutputBatcher; import de.hub.cs.dbis.aeolus.bolts.ForwardBolt; import de.hub.cs.dbis.aeolus.monitoring.MonitoringTopoloyBuilder; import de.hub.cs.dbis.aeolus.monitoring.throughput.ThroughputBolt; import de.hub.cs.dbis.aeolus.monitoring.throughput.ThroughputSpout; import de.hub.cs.dbis.aeolus.monitoring.utils.AeolusConfig; import de.hub.cs.dbis.aeolus.monitoring.utils.ConfigReader; import de.hub.cs.dbis.aeolus.sinks.FileFlushSinkBolt; import de.hub.cs.dbis.aeolus.spouts.FixedStreamRateDriverSpout; /** * TODO * * @author mjsax */ public class MeasureOutputDataRate { private final static Logger logger = LoggerFactory.getLogger(MeasureOutputDataRate.class); /** * TODO * * @throws IOException * @throws InvalidTopologyException * @throws AlreadyAliveException * @throws TException * @throws NotAliveException * */ @SuppressWarnings("unchecked") public static void main(String[] args) throws IOException, AlreadyAliveException, InvalidTopologyException, NotAliveException, TException { final String spoutId = "Spout"; final String sinkId = "Sink"; final String spoutStatisticsId = "SpoutStats"; final String sinkStatisticsId = "BoltStats"; final String topologyId = "microbenchmark-MeasureOutputDataRate"; final String spoutStatsFile = "/tmp/aeolus-spout.stats"; final String sinkStatsFile = "/tmp/aeolus-sink.stats"; String aeolusConfigFile = null; AeolusConfig aeolusConfig = null; boolean submitOrTerminate = true; // true => submit; false => terminate int i = -1; while(++i < args.length) { if(args[i].equals("-h") || args[i].equals("--help")) { printHelp(); return; } else if(args[i].equals("-c")) { ++i; if(i == args.length) { System.err.println("flag -c found but no <filename> was specified"); return; } aeolusConfigFile = args[i]; } else if(args[i].equals("--kill")) { submitOrTerminate = false; } else { System.err.println("unknown flag " + args[i]); return; } } // add $HOME/.storm as system property, such that StormSubmitter can look for storm.yaml there String userHome = System.getProperties().getProperty("user.home"); if(userHome != null) { try { Method method = URLClassLoader.class.getDeclaredMethod("addURL", new Class[] {URL.class}); method.setAccessible(true); method.invoke(ClassLoader.getSystemClassLoader(), new Object[] {new File(userHome + File.separator + ".storm").toURI().toURL()}); } catch(NoSuchMethodException e) { logger.debug("Could not add $HOME/.storm as system resource.", e); } catch(SecurityException e) { logger.debug("Could not add $HOME/.storm as system resource.", e); } catch(IllegalArgumentException e) { logger.debug("Could not add $HOME/.storm as system resource.", e); } catch(MalformedURLException e) { logger.debug("Could not add $HOME/.storm as system resource.", e); } catch(IllegalAccessException e) { logger.debug("Could not add $HOME/.storm as system resource.", e); } catch(InvocationTargetException e) { logger.debug("Could not add $HOME/.storm as system resource.", e); } } if(System.getProperty("storm.jar") == null) { System.setProperty("storm.jar", "target/monitoring-1.0-SNAPSHOT-microbenchmarks.jar"); } if(aeolusConfigFile != null) { aeolusConfig = ConfigReader.readConfig(aeolusConfigFile); } else { try { // default configuration directory within maven project aeolusConfig = ConfigReader.readConfig("src/main/resources/"); logger.trace("using {} from src/main/recources", ConfigReader.defaultConfigFile); } catch(FileNotFoundException e) { logger.debug("{} not found in src/main/recources/", ConfigReader.defaultConfigFile); try { // if started outside maven project, look at current working directory aeolusConfig = ConfigReader.readConfig(); logger.trace("using local {}", ConfigReader.defaultConfigFile); } catch(FileNotFoundException f) { logger.debug("{} not found in local working directory (.)", ConfigReader.defaultConfigFile); } } } Config stormConfig = new Config(); stormConfig.putAll(Utils.readStormConfig()); // Aeolus configuration overwrites Storm configuration if(aeolusConfig != null) { // add only if not null, otherwise StormSubmitter cannot add values from storm.yaml String nimbusHost = aeolusConfig.getNimbusHost(); if(nimbusHost != null) { logger.trace("using nimbus.host from {}", ConfigReader.defaultConfigFile); stormConfig.put(Config.NIMBUS_HOST, nimbusHost); } Integer nimbusPort = aeolusConfig.getNimbusPort(); if(nimbusPort != null) { logger.trace("using nimbus.port from {}", ConfigReader.defaultConfigFile); stormConfig.put(Config.NIMBUS_THRIFT_PORT, nimbusPort); } } // command line arguments overwrite everything stormConfig.putAll(Utils.readCommandLineOpts()); Client client = NimbusClient.getConfiguredClient(stormConfig).getClient(); if(submitOrTerminate) { final double dataRate = Double.parseDouble(System.getProperty("aeolus.microbenchmarks.dataRate")); final int batchSize = Integer.parseInt(System.getProperty("aeolus.microbenchmarks.batchSize")); final int interval = Integer.parseInt(System.getProperty("aeolus.microbenchmarks.reportingInterval")); TopologyBuilder builder = new TopologyBuilder(); // spout IRichSpout spout = new ThroughputSpout(new FixedStreamRateDriverSpout(new SchemaSpout(), dataRate), interval); if(batchSize > 0) { HashMap<String, Integer> batchSizes = new HashMap<String, Integer>(); batchSizes.put(Utils.DEFAULT_STREAM_ID, new Integer(batchSize)); spout = new SpoutOutputBatcher(spout, batchSizes); } builder.setSpout(spoutId, spout); // sink IRichBolt sink = new ThroughputBolt(new ForwardBolt(), interval, true); if(batchSize > 0) { sink = new InputDebatcher(sink); } builder.setBolt(sinkId, sink).shuffleGrouping(spoutId); // statistics builder.setBolt(spoutStatisticsId, new FileFlushSinkBolt(spoutStatsFile)).shuffleGrouping(spoutId, MonitoringTopoloyBuilder.DEFAULT_THROUGHPUT_STREAM); builder.setBolt(sinkStatisticsId, new FileFlushSinkBolt(sinkStatsFile)).shuffleGrouping(sinkId, MonitoringTopoloyBuilder.DEFAULT_THROUGHPUT_STREAM); stormConfig.setNumWorkers(4); // stormConfig.setFallBackOnJavaSerialization(false); // stormConfig.setSkipMissingKryoRegistrations(false); // stormConfig.put(Config.STORM_THRIFT_TRANSPORT_PLUGIN, // "backtype.storm.security.auth.SimpleTransportPlugin"); // stormConfig.put("storm.thrift.transport", "backtype.storm.security.auth.SimpleTransportPlugin"); SpoutOutputBatcher.registerKryoClasses(stormConfig); StormSubmitter.submitTopology(topologyId, stormConfig, builder.createTopology()); // LocalCluster c = new LocalCluster(); // c.submitTopology(topologyId, stormConfig, builder.createTopology()); String id = client.getClusterInfo().get_topologies().get(0).get_id(); TopologyInfo info = client.getTopologyInfo(id); String spoutHost = null, sinkHost = null, spoutStatsHost = null, sinkStatsHost = null; for(ExecutorSummary executor : info.get_executors()) { String operatorId = executor.get_component_id(); if(operatorId.equals(spoutId)) { spoutHost = executor.get_host(); if(spoutHost.equals(sinkHost)) { throw new RuntimeException("spout and sink deployed at same host"); } } else if(operatorId.equals(sinkId)) { sinkHost = executor.get_host(); if(sinkHost.equals(spoutHost)) { throw new RuntimeException("spout and sink deployed at same host"); } } else if(operatorId.equals(spoutStatisticsId)) { spoutStatsHost = executor.get_host(); } else if(operatorId.equals(sinkStatisticsId)) { sinkStatsHost = executor.get_host(); } } System.out.println("Aeolus.MeasureOutputDataRate.spoutHost=" + spoutHost); System.out.println("Aeolus.MeasureOutputDataRate.sinkHost=" + sinkHost); System.out.println("Aeolus.MeasureOutputDataRate.spoutStatsHost=" + spoutStatsHost); System.out.println("Aeolus.MeasureOutputDataRate.spoutStatsFile=" + spoutStatsFile); System.out.println("Aeolus.MeasureOutputDataRate.sinkStatsHost=" + sinkStatsHost); System.out.println("Aeolus.MeasureOutputDataRate.sinkStatsFile=" + sinkStatsFile); // c.killTopology(topologyId); // Utils.sleep(1000); // c.shutdown(); } else { KillOptions killOptions = new KillOptions(); killOptions.set_wait_secs(0); client.killTopologyWithOpts(topologyId, killOptions); } } /** * Prints a help dialog to stdout. */ private static void printHelp() { System.out.println("MeassureOutputDateRate start or kill the benchmark topology."); System.out.println("It supports the following flags:"); System.out.println(" -h | --help\tshows this help"); System.out.println(" -c <filename>\tsets an alternative Aeolus configuration file"); System.out .println(" --kill\tTerminates the benchmark topology. If not present, the benchmark will be started."); } }